package io.gitee.caoxiaoyu97.log.sensitive.util;


public class SensitiveInfoUtils {

    /**
     * 真实姓名脱敏(展示姓名第一个字,其余用*替换)
     * @param fullName
     * @return
     */
    public static String handleTrueName(String fullName) {
        if (fullName == null || fullName.trim().isEmpty()) {
            return "";
        }
        String name = left(fullName, 1);
        return rightPad(name, length(fullName), "*");
    }
    /**
     * 身份证号码脱敏(展示身份证号码前3位和最后4位,其余用*替换)
     * @param idCardNo
     * @return
     */
    public static String handleIdCardNo(String idCardNo) {
        if (isBlank(idCardNo)) {
            return "";
        }
        return left(idCardNo,3).concat(removeStart(leftPad(right(idCardNo, 4), length(idCardNo), "*"),"***"));
    }

    /**
     * 手机号码脱敏(展示手机号码前3位和最后4位,其余用*替换)
     * @param phoneNo
     * @return
     */
    public static String handlePhoneNo(String phoneNo) {
        if (isBlank(phoneNo)) {
            return "";
        }
        return left(phoneNo, 3).concat(removeStart(leftPad(right(phoneNo, 4),length(phoneNo), "*"), "***"));
    }

    /**
     *  银行卡号脱敏(展示银行卡号前6位和最后4位,其余用*替换)
     * @param bankcardNo
     * @return
     */
    public static String handleBankcardNo(String bankcardNo) {
        if (isBlank(bankcardNo)) {
            return "";
        }
        return left(bankcardNo, 6).concat(removeStart(leftPad(right(bankcardNo, 4), length(bankcardNo), "*"), "******"));
    }

    /**
     * 其它(全部用*替换)
     * @param msg
     * @return
     */
    public static String handleOther(String msg) {
        if (isBlank(msg)) {
            return "";
        }
        return rightPad("", length(msg), "*");
    }

    /**
     * [身份证号] 显示最后四位，其他隐藏。共计18位或者15位。<例子：*************5762>
     *
     * @param idCardNum
     * @return
     */
    public static String idCardNum(String idCardNum) {
        if (isBlank(idCardNum)) {
            return "";
        }
        String num = right(idCardNum, 4);
        return leftPad(num, length(idCardNum), "*");
    }

    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Gets the leftmost {@code len} characters of a String.</p>
     *
     * <p>If {@code len} characters are not available, or the
     * String is {@code null}, the String will be returned without
     * an exception. An empty String is returned if len is negative.</p>
     *
     * <pre>
     * left(null, *)    = null
     * left(*, -ve)     = ""
     * left("", *)      = ""
     * left("abc", 0)   = ""
     * left("abc", 2)   = "ab"
     * left("abc", 4)   = "abc"
     * </pre>
     *
     * @param str  the String to get the leftmost characters from, may be null
     * @param len  the length of the required String
     * @return the leftmost characters, {@code null} if null String input
     */
    public static String left(final String str, final int len) {
        if (str == null) {
            return null;
        }
        if (len < 0) {
            return EMPTY;
        }
        if (str.length() <= len) {
            return str;
        }
        return str.substring(0, len);
    }

    /**
     * <p>Gets the rightmost {@code len} characters of a String.</p>
     *
     * <p>If {@code len} characters are not available, or the String
     * is {@code null}, the String will be returned without an
     * an exception. An empty String is returned if len is negative.</p>
     *
     * <pre>
     * right(null, *)    = null
     * right(*, -ve)     = ""
     * right("", *)      = ""
     * right("abc", 0)   = ""
     * right("abc", 2)   = "bc"
     * right("abc", 4)   = "abc"
     * </pre>
     *
     * @param str  the String to get the rightmost characters from, may be null
     * @param len  the length of the required String
     * @return the rightmost characters, {@code null} if null String input
     */
    public static String right(final String str, final int len) {
        if (str == null) {
            return null;
        }
        if (len < 0) {
            return EMPTY;
        }
        if (str.length() <= len) {
            return str;
        }
        return str.substring(str.length() - len);
    }
    public static final String EMPTY = "";

    public static String repeat(final char ch, final int repeat) {
        if (repeat <= 0) {
            return EMPTY;
        }
        final char[] buf = new char[repeat];
        for (int i = repeat - 1; i >= 0; i--) {
            buf[i] = ch;
        }
        return new String(buf);
    }

    public static String leftPad(final String str, final int size, final char padChar) {
        if (str == null) {
            return null;
        }
        final int pads = size - str.length();
        if (pads <= 0) {
            return str; // returns original String when possible
        }
        return repeat(padChar, pads).concat(str);
    }

    public static String rightPad(final String str, final int size, final char padChar) {
        if (str == null) {
            return null;
        }
        final int pads = size - str.length();
        if (pads <= 0) {
            return str; // returns original String when possible
        }
        return str.concat(repeat(padChar, pads));
    }

    public static int length(final CharSequence cs) {
        return cs == null ? 0 : cs.length();
    }
    public static String rightPad(final String str, final int size, String padStr) {
        if (str == null) {
            return null;
        }
        if (isEmpty(padStr)) {
            padStr = SPACE;
        }
        final int padLen = padStr.length();
        final int strLen = str.length();
        final int pads = size - strLen;
        if (pads <= 0) {
            return str; // returns original String when possible
        }
        if (padLen == 1 && pads <= PAD_LIMIT) {
            return rightPad(str, size, padStr.charAt(0));
        }

        if (pads == padLen) {
            return str.concat(padStr);
        } else if (pads < padLen) {
            return str.concat(padStr.substring(0, pads));
        } else {
            final char[] padding = new char[pads];
            final char[] padChars = padStr.toCharArray();
            for (int i = 0; i < pads; i++) {
                padding[i] = padChars[i % padLen];
            }
            return str.concat(new String(padding));
        }
    }
    private static final int PAD_LIMIT = 8192;
    public static final String SPACE = " ";

    public static String removeStart(final String str, final String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (str.startsWith(remove)) {
            return str.substring(remove.length());
        }
        return str;
    }
    public static boolean isEmpty(final CharSequence cs) {
        return cs == null || cs.length() == 0;
    }
    public static String leftPad(final String str, final int size, String padStr) {
        if (str == null) {
            return null;
        }
        if (isEmpty(padStr)) {
            padStr = SPACE;
        }
        final int padLen = padStr.length();
        final int strLen = str.length();
        final int pads = size - strLen;
        if (pads <= 0) {
            return str; // returns original String when possible
        }
        if (padLen == 1 && pads <= PAD_LIMIT) {
            return leftPad(str, size, padStr.charAt(0));
        }

        if (pads == padLen) {
            return padStr.concat(str);
        } else if (pads < padLen) {
            return padStr.substring(0, pads).concat(str);
        } else {
            final char[] padding = new char[pads];
            final char[] padChars = padStr.toCharArray();
            for (int i = 0; i < pads; i++) {
                padding[i] = padChars[i % padLen];
            }
            return new String(padding).concat(str);
        }
    }
}
